package com.tanhua.manage.service;

import cn.hutool.Hutool;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.commons.key.RedisKeyConst;
import com.tanhua.manage.domain.Admin;
import com.tanhua.manage.exception.BusinessException;
import com.tanhua.manage.mapper.AdminMapper;
import com.tanhua.manage.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AdminService extends ServiceImpl<AdminMapper, Admin> {

    private static final String CACHE_KEY_CAP_PREFIX = "MANAGE_CAP_";
    public static final String CACHE_KEY_TOKEN_PREFIX="MANAGE_TOKEN_";

    @Autowired
    private RedisTemplate redisTemplate;
    //注入生成token的工具类
    @Autowired
    private JwtUtils jwtUtils;

    /**
     * 保存生成的验证码
     * @param uuid
     * @param code
     */
    public void saveCode(String uuid, String code) {
        String key = RedisKeyConst.CACHE_KEY_CAP_PREFIX + uuid;
        // 缓存验证码，10分钟后失效
        redisTemplate.opsForValue().set(key,code, Duration.ofMinutes(10));
    }

    /**
     * 获取登陆用户信息
     * @return
     */
    public Admin getByToken(String authorization) {
        String token = authorization.replaceFirst("Bearer ","");
        String tokenKey = RedisKeyConst.CACHE_KEY_TOKEN_PREFIX + token;
        String adminString = (String) redisTemplate.opsForValue().get(tokenKey);
        Admin admin = null;
        if(StringUtils.isNotEmpty(adminString)) {
            admin = JSON.parseObject(adminString, Admin.class);
            // 延长有效期 30分钟
            redisTemplate.expire(tokenKey,30, TimeUnit.MINUTES);
        }
        return admin;
    }

    /**
     * 用户登录
     */
    public String AdminLogin(Map map) {
        //获取到请求体中的账号密码 Uuid 验证码
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        String verificationCode = (String) map.get("verificationCode");
        String uuid = (String) map.get("uuid");
        //验证账号密码是否为空
        if(StringUtils.isEmpty(username)){
            throw new BusinessException("账号不能为空");
        }
        if(StringUtils.isEmpty(password)){
            throw new BusinessException("密码不能为空");
        }
        //根据uuid判断redis中验证码是否过期了 验证通过后删除redis中的验证码
        String key=RedisKeyConst.CACHE_KEY_CAP_PREFIX + uuid;
        String validateCode= (String) redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(validateCode)){
            throw new BusinessException("验证码过期了");
        }
        //验证验证码
        if(verificationCode!=null&&!validateCode.equals(verificationCode)){
            redisTemplate.delete(key);
            throw new BusinessException("验证码错误");
        }
        redisTemplate.delete(key);
        //根据账号查询admin表
        Admin admin = query().eq("username", username).one();
        if (admin==null){
            throw new BusinessException("账号不存在 请注册~");
        }
        //判断数据库中的账号和用户输入的账号是否正确
        if(!admin.getUsername().equals(username)){
            throw new BusinessException("输入的账号有误");
        }
        //判断数据库中的密码和用户输入的密码是否正确
        if(!admin.getPassword().equals(SecureUtil.md5(password))){
            throw new BusinessException("输入的密码有误");
        }
        //生成token 使用jwtt
        String token = jwtUtils.createJWT(admin.getUsername(), admin.getId());
        //将user对象转换成String 以当前用户账号和账号id作为key UserString作为value 存入redis
        String adminString = JSON.toJSONString(admin);
        String redisTokenKey=RedisKeyConst.CACHE_KEY_TOKEN_PREFIX + token;
        log.debug("正在生成token 存入redis中~");
        redisTemplate.opsForValue().set(redisTokenKey,adminString);
        //将token对象 返回给前端
        return token;
    }
    /**
     * 用户登出
     */
    public ResponseEntity logout(String token) {
        //将token进行拼接 得到redis中匹配的键
        String redisTokenKey = RedisKeyConst.CACHE_KEY_TOKEN_PREFIX + token;
        //根据指定的键删除
        redisTemplate.delete(redisTokenKey);
        //返回数据
        return ResponseEntity.ok(null);

    }
}
